package validation;

import card.*;
import validation.Type;

/**
 * To evaluate whether a given card set is valid or not
 * The major control of the validation package
 * 
 */
public class Evaluator{
	
	/**
	 * To Store the latest identified success hand
	 */
    private Type currentType;
    private TypeList fullList;
    private TypeList compareList;
    
    /**
     * Constructor
     * To set the currentType as null(Default)
     */
    public Evaluator(){
        currentType = null;	
    }
    
    /**
     * To identify the Type of a card set from player
     * @param	Cardset	Hand from player
     * @return	Type Identification result, null if invalid
     */
    private Type identify(Cardset thisHand){
    	if(currentType != null){
    		compareList = new TypeList();
    		compareList.add(Nuke.getInstance());
    		if(currentType != Nuke.getInstance())
    			compareList.add(Bomb.getInstance());
    			if(currentType != Bomb.getInstance())
    	    		compareList.add(currentType);		

    		return compareList.identify(thisHand);
    	} else {
            fullList = new TypeList();
        	fullList.add(Nuke.getInstance());
        	fullList.add(Bomb.getInstance());
        	fullList.add(Solo.getInstance());
        	fullList.add(Pair.getInstance());
        	fullList.add(Trio.getInstance());
        	fullList.add(SoloChain.getInstance());
        	fullList.add(PairChain.getInstance());
        	fullList.add(TrioChain.getInstance());
        	fullList.add(TrioWithSoloChain.getInstance());
        	fullList.add(TrioWithPairChain.getInstance());
        	fullList.add(TrioWithSolo.getInstance());
        	fullList.add(TrioWithPair.getInstance());
        	fullList.add(FourWithDualSolo.getInstance());
        	fullList.add(FourWithDualPair.getInstance());
    		
    		return fullList.identify(thisHand);
    	}
    }
    
    /**
     * Check whether the passed card set is valid in a round
     * @param Cardset Next player's hand
     * @return boolean True if valid, False if invalid
     */
    public boolean successHand(Cardset thisHand){
    	Type type = identify(thisHand);
    	if(type==null) return false;
    	
        if(currentType == null && type != null){
            currentType = type;
            return currentType.lessPriorityThan(thisHand);
        } else if(currentType == type) {
        	return currentType.lessPriorityThan(thisHand);
        } else if(type != null){
        	currentType.clear();
        	currentType = type;
        	return true;
        } else {
        	return false;
        }
            
    }
    
    /**
     * To clear the data of current round
     * Reset the currentType to null(default)
     * @return boolean True only
     */
    public boolean newRound(){
    	if(currentType != null) currentType.clear();
    	currentType = null;
    	return true;
    }
    
}